package lrscp.lib.io;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;

import lrscp.lib.Log;
import lrscp.lib.utils.StringUtils;

import org.apache.commons.io.IOUtils;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

public class CompressUtils {
    /**
     * ����Ŀ¼
     * 
     * @param outputDir
     * @param subDir
     */
    private static void createDirectory(String outputDir, String subDir) {

        File file = new File(outputDir);

        if (!(subDir == null || subDir.trim().equals(""))) {// ��Ŀ¼��Ϊ��

            file = new File(outputDir + "/" + subDir);
        }

        if (!file.exists()) {
            file.mkdirs();
        }

    }

    /**
     * ��ѹtar File
     * 
     * @param file
     *            Ҫ��ѹ��tar�ļ�����
     * @param outputDir
     *            Ҫ��ѹ��ĳ��ָ����Ŀ¼��
     * @throws IOException
     */
    public static void unTar(File file, String outputDir) throws IOException {

        TarInputStream tarIn = null;

        try {

            tarIn = new TarInputStream(new FileInputStream(file), 1024 * 2);

            createDirectory(outputDir, null);// �������Ŀ¼

            TarEntry entry = null;

            while ((entry = tarIn.getNextEntry()) != null) {

                if (entry.isDirectory()) {// ��Ŀ¼

                    createDirectory(outputDir, entry.getName());// ������Ŀ¼

                } else {// ���ļ�

                    File tmpFile = new File(outputDir + "/" + entry.getName());

                    createDirectory(tmpFile.getParent() + "/", null);// �������Ŀ¼

                    OutputStream out = null;

                    try {

                        out = new FileOutputStream(tmpFile);

                        int length = 0;

                        byte[] b = new byte[2048];

                        while ((length = tarIn.read(b)) != -1) {
                            out.write(b, 0, length);
                        }

                    } catch (IOException ex) {
                        throw ex;
                    } finally {

                        if (out != null)
                            out.close();
                    }

                }
            }

        } catch (IOException ex) {
            throw new IOException("��ѹ�鵵�ļ������쳣", ex);
        } finally {
            try {
                if (tarIn != null) {
                    tarIn.close();
                }
            } catch (IOException ex) {
                throw new IOException("�ر�tarFile�����쳣", ex);
            }
        }

    }

    /**
     * ��ѹtar.gz �ļ�
     * 
     * @param file
     *            Ҫ��ѹ��tar.gz�ļ�����
     * @param outputDir
     *            Ҫ��ѹ��ĳ��ָ����Ŀ¼��
     * @throws IOException
     */
    public static File unGz(File file, String outputDir) throws IOException {
        createDirectory(outputDir, null);
        FileInputStream fis = new FileInputStream(file);
        File target = new File(outputDir + "/" + StringUtils.removeSuffix(file.getName(), ".gz"));
        FileOutputStream fos = new FileOutputStream(target);
        IOUtils.copy(new GZIPInputStream(fis), fos);
        fis.close();
        fos.close();

        return target;
    }

    /**
     * ��ѹtar.gz �ļ�
     * 
     * @param file
     *            Ҫ��ѹ��tar.gz�ļ�����
     * @param outputDir
     *            Ҫ��ѹ��ĳ��ָ����Ŀ¼��
     * @throws IOException
     */
    public static void unTarGz(File file, String outputDir, boolean printLog) throws IOException {

        TarInputStream tarIn = null;

        try {

            tarIn = new TarInputStream(new GZIPInputStream(new BufferedInputStream(
                    new FileInputStream(file))), 1024 * 2);

            createDirectory(outputDir, null);// �������Ŀ¼

            TarEntry entry = null;

            while ((entry = tarIn.getNextEntry()) != null) {

                if (entry.isDirectory()) {// ��Ŀ¼
                    createDirectory(outputDir, entry.getName());// ������Ŀ¼
                    if (printLog)
                        Log.p("Directory:" + entry.getName());
                } else {// ���ļ�

                    File tmpFile = new File(outputDir + "/" + entry.getName());
                    if (printLog)
                        Log.p("extract:" + tmpFile.getAbsolutePath());
                    createDirectory(tmpFile.getParent() + "/", null);// �������Ŀ¼

                    OutputStream out = null;

                    try {

                        out = new FileOutputStream(tmpFile);

                        int length = 0;

                        byte[] b = new byte[2048];

                        while ((length = tarIn.read(b)) != -1) {
                            out.write(b, 0, length);
                        }

                    } catch (IOException ex) {
                        throw ex;
                    } finally {

                        if (out != null)
                            out.close();
                    }

                }
            }

        } catch (IOException ex) {
            throw new IOException("��ѹ�鵵�ļ������쳣", ex);
        } finally {
            try {
                if (tarIn != null) {
                    tarIn.close();
                }
            } catch (IOException ex) {
                throw new IOException("�ر�tarFile�����쳣", ex);
            }
        }

    }

}
